package com.nintendo.bubblechat.service.impl;

import com.nintendo.bubblechat.config.MinioConfig;
import com.nintendo.bubblechat.entity.pojo.FriendsRequest;
import com.nintendo.bubblechat.entity.dto.GroupChatDTO;
import com.nintendo.bubblechat.entity.pojo.GroupChat;
import com.nintendo.bubblechat.entity.pojo.GroupChatMsg;
import com.nintendo.bubblechat.entity.vo.UsersVo;
import com.nintendo.bubblechat.exceptions.GraceException;
import com.nintendo.bubblechat.grace.result.GraceJsonRequest;
import com.nintendo.bubblechat.grace.result.ResponseStatusEnum;
import com.nintendo.bubblechat.mapper.FriendsRequestMapper;
import com.nintendo.bubblechat.mapper.UsersMapper;
import com.nintendo.bubblechat.service.FriendRequestService;
import com.nintendo.bubblechat.service.UsersService;
import com.nintendo.bubblechat.utils.MinioUtils;
import org.apache.catalina.User;
import org.n3r.idworker.Sid;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class FriendRequestServiceImpl implements FriendRequestService {
    @Autowired
    private FriendsRequestMapper friendsRequestMapper;
    @Autowired
    private UsersService usersService;
    @Autowired
    private UsersMapper userMapper;
    @Autowired
    private Sid sid;
    @Autowired
    private MinioConfig minioConfig;
    @Autowired
    private MinioUtils minioUtils;
    @Override
    public void saveRequest(FriendsRequest friendRequest) {
        FriendsRequest request = findRequest(friendRequest.getSendUserId(), friendRequest.getAcceptUserId());
        if(request!=null){
            GraceException.display(ResponseStatusEnum.USER_FRIEND_REQUEST_EXIST_ERROR);
        }
        friendRequest.setRequestDateTime(new Date());
        friendRequest.setId(sid.nextShort());
        friendsRequestMapper.saveRequest(friendRequest);
    }

    @Override
    public List<UsersVo> findRequest(String acceptUserId) {
        List<String> requestUserIds = findRequestUserIds(acceptUserId);
        if(!requestUserIds.isEmpty()&&requestUserIds!=null){
            return usersService.findUserByUserIds(requestUserIds);
        }
        return null;
    }

    @Override
    public void ignore(FriendsRequest request) {
        friendsRequestMapper.ignoreRequest(request);
    }

    @Override
    @Transactional
    public void pass(FriendsRequest request) {
        friendsRequestMapper.ignoreRequest(request); // 删除字段
        request.setId(sid.nextShort());
        friendsRequestMapper.pass(request);
        String acceptUserId = request.getAcceptUserId();
        String sendUserId = request.getSendUserId();
        FriendsRequest my = new FriendsRequest();
        my.setId(sid.nextShort());
        my.setAcceptUserId(sendUserId);
        my.setSendUserId(acceptUserId);
        friendsRequestMapper.pass(my);
    }

    @Override
    public List<UsersVo> findMyFriends(String myUserId) {
       List<UsersVo> usersVos =  friendsRequestMapper.findMyFriends(myUserId);
        return usersVos;
    }

    @Override
    public void createGroup(GroupChatDTO groupChatDTO) {
        GroupChat groupChat = new GroupChat();
        groupChat.setId(sid.nextShort());
        BeanUtils.copyProperties(groupChatDTO,groupChat);
        List<String> ids = groupChat.getIds(); // 朋友ids
        String imageGrid = null;
        List<String> imageUrls = findUserInfoByIds(ids);
        try {
            imageGrid = createImageGrid(imageUrls);
        } catch (Exception e) {
            e.printStackTrace();
        }
        for (String id : ids){
            friendsRequestMapper.createGroup(groupChat.getId(),groupChat.getCreateUserId(),new Date(),id,imageGrid);
        }
        friendsRequestMapper.createGroup(groupChat.getId(),groupChat.getCreateUserId(),new Date(),groupChat.getCreateUserId(),imageGrid);
    }
    public List<String> findUserInfoByIds(List<String> ids){
        List<UsersVo> userByUserIds = userMapper.findUserByUserIds(ids);
        List<String> userImages = new ArrayList<>();
        for (UsersVo user : userByUserIds){
            userImages.add(user.getFace());
        }
        return userImages;
    }
    @Override
    public List<GroupChat> findMyGroupAndIn(String myId) {
        List<GroupChat> groupChats = friendsRequestMapper.findMyGroupAndIn(myId);
        return groupChats;
    }

    @Override
    public List<UsersVo> getGroupMembers(String groupId) {
        List<UsersVo> usersVos = friendsRequestMapper.findGroupMembers(groupId);
        return usersVos;
    }

    @Override
    public String saveGroupChatMsg(GroupChatMsg groupChatMsg) {
        String sid = this.sid.nextShort();
        groupChatMsg.setId(sid);
        groupChatMsg.setCreateTime(new Date());
        groupChatMsg.setSignFlag(0);
        friendsRequestMapper.saveGroupChatMsg(groupChatMsg);
        return sid;
    }

    @Override
    public List<GroupChat> getGroupInfo(String groupId) {
        List<GroupChat> chats = friendsRequestMapper.findGroupInfo(groupId);
        return chats;
    }

    private FriendsRequest findRequest(String sendUserId, String acceptUserId) {

        return friendsRequestMapper.findRequest(sendUserId,acceptUserId);
    }
    private List<String> findRequestUserIds(String acceptUserId){
        return friendsRequestMapper.findRequestIds(acceptUserId);
    }

    /**
     *生成九宫格图片
     */

    /**
     * 接收最多9张图片的URL地址，生成九宫格图片并上传到 MinIO 服务器
     *
     * @param imageUrls 图片URL列表
     * @return MinIO 中新生成图片的访问地址
     * @throws IOException 如果图片加载失败或文件写入失败
     */
    public String createImageGrid(List<String> imageUrls) throws Exception {
        // 确保图片数量不超过9张
        if (imageUrls.size() > 9 || imageUrls.isEmpty()) {
            throw new IllegalArgumentException("图片数量必须在1到9之间");
        }

        // 定义每个小图的尺寸（可以根据需要调整）
        int cellWidth = 200;
        int cellHeight = 200;

        // 计算九宫格的行数和列数
        int rows = (int) Math.ceil(imageUrls.size() / 3.0);
        int cols = Math.min(imageUrls.size(), 3);

        // 创建一个新的空白图片作为画布
        BufferedImage gridImage = new BufferedImage(
                cols * cellWidth, rows * cellHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = gridImage.createGraphics();
        g2d.setColor(Color.WHITE); // 设置背景色为白色
        g2d.fillRect(0, 0, cols * cellWidth, rows * cellHeight);

        // 遍历图片URL列表，将每张图片绘制到九宫格中
        for (int i = 0; i < imageUrls.size(); i++) {
            String imageUrl = imageUrls.get(i);
            BufferedImage img = ImageIO.read(new URL(imageUrl));

            // 缩放图片以适应单元格大小
            img = resizeImage(img, cellWidth, cellHeight);

            // 计算图片的位置
            int row = i / 3;
            int col = i % 3;
            int x = col * cellWidth;
            int y = row * cellHeight;

            // 将图片绘制到画布上
            g2d.drawImage(img, x, y, null);
        }
        g2d.dispose();

        // 将生成的图片转换为字节数组
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(gridImage, "jpg", baos);
        byte[] imageBytes = baos.toByteArray();

        // 调用 MinIO 上传方法
        ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
        MultipartFile multipartFile = new MockMultipartFile("grid.jpg", "grid.jpg", "image/jpeg", inputStream);
        String uploadedPath = minioUtils.upload(multipartFile);
        uploadedPath ="http://"+minioConfig.getEndpoint()+":"+minioConfig.getPort()+"/"+uploadedPath;
        return uploadedPath;
    }

    /**
     * 调整图片大小
     *
     * @param originalImage 原始图片
     * @param width         目标宽度
     * @param height        目标高度
     * @return 调整后的图片
     */
    private BufferedImage resizeImage(BufferedImage originalImage, int width, int height) {
        BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = resizedImage.createGraphics();
        g.drawImage(originalImage, 0, 0, width, height, null);
        g.dispose();
        return resizedImage;
    }
}
